function varargout = TLManageDocCtrls(action,varargin)

%TLMANAGEDOCCTRLS Summary of this function goes here
%
%   TLMANAGEDOCCTRLS(varagin) Detailed explanation goes here
%
%   Inputs:
%
%
%   Outputs:
%
%
%   Syntax:
%
%
%   Example:
%
%
%   See also:
%
% 
%   Author(s): Xiaobiao Huang
%   Copyright 2013-2020 The Xiaobiao Studio.
%   $Revision: 1.0.0.0 $  $Date: 05-Jul-2013 21:47:00 $

% TL_MANAGE_DOC_CTRLS manages documentation controls for block dialogs
%   The first input parameter denotes an action string for dialog handling.
%
% SYNTAX [sheetDims, ctrlPos] = tl_manage_doc_ctrls(commonGeom,sheetDims,bCodeComment,bTblBlock)
%   Determine position of documentation controls
%
%   INPUT ARGUMENTS
%   commonGeom    common geometry control positions
%   sheetDims     dimension of sheet
%   bCodeComment  should code comment be available
%   bTblBlock     flag =1 if block is table block, =0 otherwise
%
%   OUTPUT ARGUMENTS
%   sheetDims     dimension of sheet
%   ctrlPos       positions of controls with scaling data frame
%
% SYNTAX dlgdata = tl_manage_doc_ctrls('create',dlgfig,pageNum,dlgdata)
%   Create controls of documentation tab
%
%   INPUT ARGUMENTS
%   dlgfig        handle for dialog figure
%   pageNum       number of page
%   dlgdata       dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata       dialog data
%
% SYNTAX [dlgdata,bModified] = tl_manage_doc_ctrls('callback',pageNum,dlgfig,dlgdata,control)
%   Manage callback actions of documentation tab
%
%   INPUT ARGUMENTS
%   pageNum       number of page
%   dlgfig        handle for dialog figure
%   dlgdata       dialog data
%   control       control that triggers a callback
%
%   OUTPUT ARGUMENTS
%   dlgdata       dialog data
%   bModified     dialog data has changed
%
% SYNTAX [dlgdata] = tl_manage_doc_ctrls('update',pageNum,dlgfig,dlgdata)
%   Update controls of documentation tab
%
%   INPUT ARGUMENTS
%   pageNum       number of page
%   dlgfig        handle for dialog figure
%   dlgdata       dialog data
%
%   OUTPUT ARGUMENTS
%   -/-


% Author(s): C. Witte, T. Pietzsch, D. Andoleit
% $RCSfile: tl_manage_doc_ctrls.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_GeneralUI/Sources/MSrc/project.pj $
% $Revision: 1.7 $
% $Date: 2011/03/17 15:10:26MEZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    case 'create' % create the documentation page
        % identify input arguments
        pageNum = varargin{1};
        dlgfig  = varargin{2};
        dlgdata = varargin{3};

        ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;

        if dlgdata.bIsFullVs == 1
            whiteColor = 'w';
            editEnable = 'on';
        else
            whiteColor = get(dlgfig,'Color');
            editEnable = 'inactive';
        end

        %-------------------------------------
        %  get a fixed width font if available
        %-------------------------------------

        %we have to check which font we can use
        %version for iso conform fonts

        try
            systemInfo = ds_get_systeminfo;
            if systemInfo.MultiBytePage > 0
                %we have a sytsem which migth not have Courier New
                % for example on japanese windows
                FontName = get(0,'FixedWidthFontName');
            else
                %we have an  all fonts availabe, which are conform
                % to the weastern iso standard, so we have  Courier New
                FontName = 'Courier New';
            end

        catch
            FontName = 'Courier New';
				end

				pageName = dlgdata.pageNames{pageNum};
        %---------------------------------------
        % edit field to display documentation
        %---------------------------------------
        Children.blockCommentEditLabel = uicontrol( ...
            'Parent',             dlgfig, ...
            'String',             'Block comment:', ...
            'Style',              'text', ...
            'Position',           ctrlPos.blockCommentLabel);

        Children.blockCommentEdit = uicontrol( ...
            'Parent',             dlgfig, ...
            'BackgroundColor',    whiteColor, ...
            'Enable',             editEnable, ...
            'Min',                0, ...
            'FontName',          FontName, ...
            'FontSize',           9, ...
            'Max',                2, ...
            'String',             dlgdata.data.blockcomment, ...
            'Style',              'edit', ...
            'Position',           ctrlPos.blockCommentEdit, ...
						'Callback',           sprintf('tldlg(''%s'',gcbf,''blockCommentEdit'')',pageName));

        %---------------------------------------
        % code comment
        %---------------------------------------
        if isfield(dlgdata.data,'comment')
            Children.codecommentEditLabel = uicontrol( ...
                'Parent',             dlgfig, ...
                'String',             'Code comment:', ...
                'Style',              'text', ...
                'Position',           ctrlPos.codeCommentLabel);

            Children.codeCommentEdit = uicontrol( ...
                'Parent',             dlgfig, ...
                'BackgroundColor',    whiteColor, ...
                'Enable',             editEnable, ...
                'Min',                0, ...
                'FontName',           FontName, ...
                'FontSize',           9, ...
                'Max',                2, ...
                'String',             dlgdata.data.comment.text, ...
                'Style',              'edit', ...
                'Position',           ctrlPos.codeCommentEdit, ...
						    'Callback',           sprintf('tldlg(''%s'',gcbf,''codeCommentEdit'')',pageName));

            if isfield(dlgdata.data.comment,'placement')
                Children.declinsertRadiobutton = uicontrol( ...
                    'Parent',dlgfig, ...
                    'Style', 'radiobutton', ...
                    'Enable',flag2str(dlgdata.bIsFullVs), ...
                    'String','Insert at block variable declaration', ...
                    'Value', (dlgdata.data.comment.placement == 1), ...
                    'Position',ctrlPos.declinsertRadiobutton, ...
										'Callback',sprintf('tldlg(''%s'',gcbf,''declinsertRadiobutton'')',pageName));

                Children.evalInsertRadiobutton = uicontrol( ...
                    'Parent',dlgfig, ...
                    'Style', 'radiobutton', ...
                    'Enable',flag2str(dlgdata.bIsFullVs), ...
                    'String','Insert at block variable evaluation', ...
                    'Value', (dlgdata.data.comment.placement == 2), ...
                    'Position',ctrlPos.evalInsertRadiobutton, ...
										'Callback',sprintf('tldlg(''%s'',gcbf,''evalInsertRadiobutton'')',pageName));
            end
        elseif isfield(dlgdata.data,'codecomment')
            Children.codecommentEditLabel = uicontrol( ...
                'Parent',             dlgfig, ...
                'String',             'Code comment:', ...
                'Style',              'text', ...
                'Position',           ctrlPos.codeCommentLabel);

            Children.codeCommentEdit = uicontrol( ...
                'Parent',             dlgfig, ...
                'BackgroundColor',    whiteColor, ...
                'Enable',             editEnable, ...
                'Min',                0, ...
                'FontName',           FontName, ...
                'FontSize',           9, ...
                'Max',                2, ...
                'String',             dlgdata.data.codecomment, ...
                'Style',              'edit', ...
                'Position',           ctrlPos.codeCommentEdit, ...
								'Callback',           sprintf('tldlg(''%s'',gcbf,''codeCommentEdit'')',pageName));
        end

        dlgdata.pageData{pageNum}.children = Children;
        varargout{1} = dlgdata;

    case 'callback'
        pageNum  = varargin{1};
        dlgdata  = varargin{3};
        control  = varargin{4};
        Children = dlgdata.pageData{pageNum}.children;

        switch control
            case 'blockCommentEdit'
                dlgdata.data.blockcomment = FcnTrimComment(get(Children.blockCommentEdit,'String'));
                % mark blockdata as changed
                dlgdata.data.date = now;
            case 'codeCommentEdit'
                if isfield(dlgdata.data,'comment')
                    dlgdata.data.comment.text = FcnTrimComment(get(Children.codeCommentEdit,'String'));
                else % the function block has a property codecomment instead of comment
                    dlgdata.data.codecomment = FcnTrimComment(get(Children.codeCommentEdit,'String'));
                end
            case {'declinsertRadiobutton','evalInsertRadiobutton'}
                placebuttons = [Children.declinsertRadiobutton Children.evalInsertRadiobutton];
                pressedButton = Children.(control);
                ds_handle_radiobuttons(placebuttons, pressedButton);
                dlgdata.data.comment.placement = find(placebuttons == pressedButton);

            otherwise
                error('Invalid callback');
        end
        varargout{1} = dlgdata;
        varargout{2} = 1; %bModified;

    case 'ctrlpos' % calculate control positions
        commonGeom    = varargin{1};
        sheetDims     = varargin{2};
        bCodeComment  = varargin{3};
        bTblBlock     = varargin{4};
        [sheetDims, ctrlPos] = FcnDocCtrlPositions( ...
            commonGeom,sheetDims,bCodeComment,bTblBlock);
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'update'
        pageNum = varargin{1};
        dlgdata = varargin{3};
        Children = dlgdata.pageData{pageNum}.children;

        set(Children.blockCommentEdit, 'String', dlgdata.data.blockcomment);
        if isfield(dlgdata.data,'comment')
            set(Children.codeCommentEdit, 'String', dlgdata.data.comment.text);
            if isfield(dlgdata.data.comment,'placement')
                set(Children.declinsertRadiobutton, 'Value', ...
                    (dlgdata.data.comment.placement == 1));
                set(Children.evalInsertRadiobutton, 'Value', ...
                    (dlgdata.data.comment.placement == 2));
            end
        elseif isfield(dlgdata.data, 'codecomment')
            set(Children.codeCommentEdit, 'String', dlgdata.data.codecomment);
        end
        varargout = {};

    otherwise
        error('Invalid Action');
end


%--------------------------------------------------------------------------
% FcnDocCtrlPositions calculates positions for all doc ctrls & return the
% total
%
% INPUT ARGUMENTS
%   commonGeom      commonly used geometry values
%   sheetDims       width and height of tab page
%   bCodeComment    flag which is true if page should contain an code
%                   comment edit field
%   bTblBlock       tab page belongs to one of the table dialogs
%
% OUTPUT ARGUMENTS
%   sheetDims       see above
%   ctrlPos         structure with calculated control positions
%--------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnDocCtrlPositions(commonGeom,sheetDims,bCodeComment,bTblBlock)

[blockCommentLabelSize, ...
    codeCommentLabelSize, ...
    declinsertRadiobuttonSize, ...
    evalInsertRadiobuttonSize, ...
    clipboardButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom,{ ...
    'Block Comment:',                         'text';
    'Code Comment',                           'text';
    'Insert at block variable declaration',   'radiobutton';
    'Insert at block variable evaluation',    'radiobutton';
    'Copy To Clipboard',                      'pushbutton'});

rowDelta = 5;
colDelta = 25;

% proportion between code comment and block comment should be 1:2
% but codecomment must not be less than two lines
% (one line for heading and one edit line)

minSheetHeight = commonGeom.sheetTopEdgeBuffer ...
    + 3 * commonGeom.editHeight ...
    + commonGeom.sheetBottomEdgeBuffer;
if bCodeComment,
    minSheetHeight = minSheetHeight ...
        + 3 * commonGeom.editHeight;
end
if bTblBlock,
    tblNameDispHeight = rowDelta + commonGeom.editHeight;
    minSheetHeight = minSheetHeight + tblNameDispHeight;
else
    tblNameDispHeight = 0;
end

% now decide if sheet dimensions must grow or not
sheetDims(2) = max(sheetDims(2),minSheetHeight);

% calculate place for comment boxes
availHeight = sheetDims(2) - tblNameDispHeight - commonGeom.sheetTopEdgeBuffer - commonGeom.sheetBottomEdgeBuffer;

% calculate size for code comment edit field
if bCodeComment,
    codeCommentEditHeight = (availHeight ...
        - 3 * commonGeom.editHeight) / 3;
    availHeight = availHeight ...
        - codeCommentEditHeight ...
        - rowDelta ...
        - commonGeom.editHeight ...
        - rowDelta;
else
    codeCommentEditHeight = 0;
end
commentBoxWidth = sheetDims(1) - 2 * commonGeom.frameSideEdgeBuffer;
codeCommentEditSize = [commentBoxWidth,codeCommentEditHeight];

% calculate size for block comment
blockCommentEditHeight = availHeight ...
    - commonGeom.textHeight;
blockCommentEditSize = [commentBoxWidth,blockCommentEditHeight];

% block comment edit field
cx = commonGeom.sheetSideEdgeBuffer + commonGeom.figSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + commonGeom.sheetBottomEdgeBuffer;

ctrlPos.blockCommentEdit = [cx cy blockCommentEditSize];

% block comment label
cy = cy + blockCommentEditSize(2);
ctrlPos.blockCommentLabel = ...
    [cx cy blockCommentLabelSize];

% code comment controls
if bCodeComment,
    % code comment edit field
    cy = cy + commonGeom.editHeight + rowDelta;
    ctrlPos.codeCommentEdit = [cx cy codeCommentEditSize];
    % code comment label
    cy = cy + codeCommentEditSize(2);
    ctrlPos.codeCommentLabel = [cx cy codeCommentLabelSize];
    % radiobutton 'insert at block variable declaration'
    rowPos = sum(ctrlPos.blockCommentEdit([1 3])) - evalInsertRadiobuttonSize(1);
    ctrlPos.evalInsertRadiobutton = ...
        [rowPos cy evalInsertRadiobuttonSize];
    % radiobutton 'insert at block variable evaluation'
    rowPos = rowPos - declinsertRadiobuttonSize(1) - 5;
    ctrlPos.declinsertRadiobutton = ...
        [rowPos cy declinsertRadiobuttonSize];
end

% table function name controls
if bTblBlock
    % text field that displays the table function name
    cy = cy + commonGeom.editHeight + rowDelta;
    availWidth = sheetDims(1) ...
        - cx ...
        - colDelta / 3 ...
        - clipboardButtonSize(1) ...
        - commonGeom.sheetSideEdgeBuffer;
    ctrlPos.tblFcnName = [cx,cy,availWidth,commonGeom.textHeight];
    % button to copy table function name to clipboard
    cx = sheetDims(1) - commonGeom.sheetSideEdgeBuffer - clipboardButtonSize(1);
    ctrlPos.clipboardButton = [cx,cy,clipboardButtonSize];
end


%--------------------------------------------------------------------------
% FcnTrimComment trims the code or block comment
%
% INPUT ARGUMENTS
%   comment     raw comment
%
% OUTPUT ARGUMENTS
%   comment     treated comment
%--------------------------------------------------------------------------
function comment = FcnTrimComment(comment)

% convert string into cell of strings and trim each line
comment = strtrim(cellstr(comment));
% remove emtpy lines
while numel(comment) > 1 && isempty(comment{end})
    comment(end) = [];
end
comment = sprintf('%s\n',comment{:});
% remove last \n
comment(end) = [];

% end % end of function  TLManageDocCtrls
